#include "SpriteSheet.h"
#include "SDL.h"
#include "SDL_opengl.h"
#include "SDL_image.h"
#include <iostream>

using namespace std;

SpriteSheet::SpriteSheet(const std::string& fileName, short tileW, short tileH, short tileS, short tileM):
	tileWidth(tileW), tileHeight(tileH), tileSpacing(tileS), tileMargin(tileM)
{	
	SDL_Surface* tileset = IMG_Load(fileName.c_str());
	if (!tileset)
		cout << "failed to load tileset" << endl;
	
	tilesetHeight = tileset->h;
	tilesetWidth = tileset->w;
	
	tileCols = ((tileset->w) - (2 * tileMargin) + tileSpacing) / (tileWidth + tileSpacing);
	tileRows = ( (tileset->h) - (2 * tileMargin) + tileSpacing) / (tileHeight + tileSpacing);
	
	coordinates = vector<vector<TexCoords*> >( tileRows, vector<TexCoords*>( tileCols, NULL) );
	
	glGenTextures(1, &texture);
	
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,tileset->w,tileset->h,0,GL_RGBA,GL_UNSIGNED_BYTE,tileset->pixels);
	
	SDL_FreeSurface(tileset);
}

TexCoords* SpriteSheet::getTexCoords(int row, int col)
{
	if (row < 0 || row > (tileRows - 1) || col < 0 || col > (tileCols - 1))
		throw "Coordinate index out of bounds!";
	
	TexCoords* tc = coordinates[row][col];
	
	if (tc)
	{
		return tc;
	}
	
	GLfloat s,t = 0;
	
	int pixelX = tileMargin + ( col * (tileSpacing + tileWidth) );
	int pixelY = tileMargin + ( (tileRows - row - 1) * (tileSpacing + tileHeight) );
	
	s = ( (GLfloat)pixelX ) / tilesetWidth;
	t = ( (GLfloat)pixelY ) / tilesetHeight;
	
	
	GLfloat unitS = ( (GLfloat)tileWidth ) / tilesetWidth;
	GLfloat unitT = ( (GLfloat)tileHeight ) / tilesetHeight;
	
	TexCoords* newCoords = new TexCoords(s,t,unitS,unitT);
	
	coordinates[row][col] = newCoords;
	return newCoords;
}

short SpriteSheet::getTileWidth()
{
	return tileWidth;
}

short SpriteSheet::getTileHeight()
{
	return tileHeight;
}

GLuint SpriteSheet::getTextureInt()
{
	return texture;
}